/**
 * 
 */
package com.nari.basic.dao;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.nari.basic.model.IMenu;
import com.nari.basic.utils.sysmgr.UserRoleUtil;
import com.nari.coreframe.dao.hibernate3.GenericDaoImpl;
import com.nari.platform.utils.StringUtils;

/**
 * 
 * @author Xiaopeng
 * @date 2013-7-18
 */
public class MenuDaoImpl extends GenericDaoImpl<IMenu, String> implements IMenuDao {
	
	/**
	 * 查询系统所有菜单
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-23
	 */
	public List<IMenu> queryAllMenusInOrder() throws Exception {
		String queryMenuHql = "from IMenu m " +
				"order by m.orderID,m.createTime desc";
		return this.runQueryHSql(queryMenuHql);
	}

	/**
	 * 通过角色唯一识别码查询其对应的菜单列表
	 * @param roleUIDs 角色唯一识别码
	 *   格式：XXX,XXX,XXX
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-22
	 */
	public List<IMenu> queryUserMenuByRoleUIDs(String roleUIDs) throws Exception {
		if(roleUIDs!=null && !"".equals(roleUIDs)) {
			String formatRoleUIDs = StringUtils.formatIDListWithSyntax(roleUIDs, ",", "'");
			String queryMenuHql = "from IMenu m " +
					"where m.id in(select distinct rm.menuUuid " +
								"from IRoleMenu rm " +
								"where rm.roleUuid in("+formatRoleUIDs+")) " +
					"order by m.orderID,m.createTime desc";
			return this.runQueryHSql(queryMenuHql);
		}
		return null;
	}
	
	/**
	 * 查询菜单根节点，并过滤出权限菜单（需要情况下）
	 * @param authorityMenuList 权限菜单，默认无权限过滤
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-23
	 */
	public List<IMenu> queryFirstLevelMenu(List<IMenu> authorityMenuList) throws Exception {
		StringBuffer queryMenuHql = new StringBuffer("from IMenu m where m.parentID is null ");
		if(authorityMenuList != null) {
			String idList = UserRoleUtil.formatIDByMenuList(authorityMenuList);
			String idFormat = StringUtils.formatIDListWithSyntax(idList, ",", "'");
			queryMenuHql.append("and m.id in(");
			queryMenuHql.append(idFormat);
			queryMenuHql.append(") ");
		}
		queryMenuHql.append("order by m.orderID,m.createTime desc");
		return this.runQueryHSql(queryMenuHql.toString());
	}
	
	/**
	 * 根据父菜单ID查询子菜单节点，并过滤出权限菜单（需要情况下）
	 * @param pMenuID 若父菜单不存在，则查询根节点
	 * @param authorityMenuList 权限菜单，默认无权限过滤
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-23
	 */
	public List<IMenu> queryChildMenuByParent(String pMenuID, List<IMenu> authorityMenuList) throws Exception {
		StringBuffer queryMenuHql = new StringBuffer("from IMenu m ");
		if(pMenuID!=null && !"".equals(pMenuID.trim())) {
			queryMenuHql.append("where m.parentID='");
			queryMenuHql.append(pMenuID);
			queryMenuHql.append("' ");
		} else {
			queryMenuHql.append("where (m.parentID is null or m.parentID='') ");
		}
		if(authorityMenuList != null) {
			String idList = UserRoleUtil.formatIDByMenuList(authorityMenuList);
			String idFormat = StringUtils.formatIDListWithSyntax(idList, ",", "'");
			queryMenuHql.append("and m.id in(");
			queryMenuHql.append(idFormat);
			queryMenuHql.append(") ");
		}
		queryMenuHql.append("order by m.orderID,m.createTime desc");
		return this.runQueryHSql(queryMenuHql.toString());
	}
	
	/**
	 * 通过菜单名称模糊查询
	 * @param menuName
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-24
	 */
	@SuppressWarnings("unchecked")
	public List<IMenu> queryByMenuNameLike(String menuName) throws Exception {
		Criteria criteria = this.getCurrentSession().createCriteria(IMenu.class);
		if(menuName!=null && !"".equals(menuName.trim())) {
			criteria.add(Restrictions.ilike("menuName", menuName.trim(), MatchMode.ANYWHERE));
		}
		criteria.addOrder(Order.asc("orderID")).addOrder(Order.desc("createTime"));
		return criteria.list();
	}
	
	/**
	 * 通过父菜单ID统计其子菜单的个数
	 * @param pMenuID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-7-24
	 */
	public int countChildrenByPMenuID(String pMenuID) throws Exception {
		String hsql ="select count(*) " +
				"from IMenu m " +
				"where m.parentID='"+pMenuID+"'";
		return ((Long)this.runQueryHSqlObject(hsql).get(0)).intValue();
	}
	
	/**
	 * 通过菜单链接查询查询信息
	 * @param menuAction
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-3-25
	 */
	public IMenu queryMenuByMenuAction(String menuAction) throws Exception {
		IMenu menu = null;
		if(menuAction!=null && !"".equals(menuAction.trim())) {
			String hsql = "from IMenu m where m.menuAction='"+menuAction+"'";
			List<IMenu> menuList = this.runQueryHSql(hsql);
			if(menuList!=null && menuList.size()>0) {
				menu = menuList.get(0);
			}
		}
		return menu;
	}
	
	/**
	 * 通过菜单ID序列查询菜单列表，并按原序列顺序返回
	 * @param menuUidSeq
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-3-25
	 */
	public List<IMenu> queryMenuListBySeq(String menuUidSeq) throws Exception {
		List<IMenu> menuList = null;
		if(menuUidSeq!=null && !"".equals(menuUidSeq)) {
			menuUidSeq = menuUidSeq.replaceAll("[.]", ",");
			String menuUidSeqFormat = StringUtils.formatIDListWithSyntax(menuUidSeq, ",", "'");
			/* 查用数据库按照in中条件排序说明：
			 * 1、MySQL中通过in查询怎样排序问题：两种方法，即order by substring_index和order by find_in_set
			 * substring_index(源字符串, 目标字符串, 起始位置)
			 * find_in_set(目标字符串, 源字符串)：缺点是如果不小心加了多余的空格就会有问题，所以一定要小心使用
			 * 示例：order by find_in_set(id,'179906362505, 63323849672846, 1842319481513')
			 * 2、Oracle中实现查询结果按照in中条件排序：instr(源字符串, 目标字符串, 起始位置, 匹配序号)
			 * 示例：order by instr('155977,172505,155967,155952', id) 
			 * 3、HQL中尚未查到对应通用函数
			 * */
			String hsql = "from IMenu m " +
					"where m.id in("+menuUidSeqFormat+") " +
					"order by substring_index('"+menuUidSeq+"', m.id, 1)";
			menuList = this.runQueryHSql(hsql);
		}
		return menuList;
	}
	
}
